<template>
  <page-meta :root-font-size="rootFontSize() + 'px'"> </page-meta>

  <view class="page-container" v-show="delayShow">
    <customHeader :isShowProcess="!isLearnFinish" :progress="progress" :title="headerTitle" />

    <view class="page-content" :style="{ top: !isLearnFinish ? processTopHeight : height }">
      <view class="page-wrapper">
        <template v-if="!isLearnFinish">
          <template v-if="isUpdate">
            <skillVideo v-if="currentQuestion.type === 3" :session_id="session_id" :part_id="currentQuestion.part_id"
              :video="currentQuestion.video" :video_process="currentQuestion.video_process"
              @video-next="handleVideoNodeReport" />

            <skillWord v-if="currentQuestion.type === 0" :question="currentQuestion" />
            <skillSentence v-if="[1, 2].includes(currentQuestion.type)" class="wrapper-sentence"
              :question="currentQuestion" @update="updateCurrentQuestion" />
          </template>

          <template v-if="currentQuestion.type !== 3">
            <recordSound ref="recordRef" v-if="!currentQuestion.user_voice" title="Speaking" :prevIconUrl="prevIconUrl"
              :nextIconUrl="nextIconUrl" @prev="handleToPrev" @next="handleToNext"
              @on-upload-success="onRecorderSuccess" />

            <view v-else class="operate-buttons">
              <recordSound :isSetSlot="true" @on-upload-success="onRecorderSuccess">
                <template #main-button="{ slotEvent }">
                  <view class="button-wrapper">
                    <image class="wrapper-switch" :src="prevIconUrl" @click="handleToPrev" />
                    <button class="wrapper-btn minor" @click="handleListenOriginVoice">
                      <loudspeaker ref="speakerRef" class="btn-icon" :voice="currentQuestion.us_voice" />
                      原文
                    </button>
                    <button class="wrapper-btn prime" @click="slotEvent('reRecord')">
                      <image class="btn-icon" src="https://rwstatic.tentons.cn/web/Lesson/images/replay-icon.png" />
                      重录
                    </button>
                    <image class="wrapper-switch" :src="nextIconUrl" @click="handleToNext" />
                  </view>
                </template>
              </recordSound>
            </view>
          </template>
        </template>

        <skillResult class="wrapper-result" v-else :isRelearn="isRelearn" :session_id="session_id" :headerTitle="subTitle"
          :isReStart="isReStart" :result="skillResults" @reStart="handleReStart" />
      </view>
    </view>
  </view>

  <CwCommon />
</template>

<script setup lang="ts">
import { computed, nextTick, onBeforeUnmount, ref } from "vue";
import { onLoad } from "@dcloudio/uni-app";
import { rootFontSize, util } from "@/utils/util";
import skillWord from "./skillWord.vue";
import skillVideo from "./skillVideo.vue";
import skillSentence from "./skillSentence.vue";
import skillResult from "./skillResult.vue";
import loudspeaker from "@/components/loudspeaker.vue";
import recordSound, { type IUploadSuccessInfo } from "@/components/recordSound.vue";
import { startEvaluating } from "@/utils/chivox";
import API from "@/api";
import type { ISkillResult } from "./index";
import type { ILessonResult } from "@/pages/lowPricedCourse/trialCourseHome/courseList/index.vue";
import { requestSoundExplanationData } from "./index";
import { useDelayShow } from "@/hooks/useDelayShow";

const speakingPrev = "https://rwstatic.tentons.cn/web/Lesson/images/speaking-prev.png";
const speakingPrevActive = "https://rwstatic.tentons.cn/web/Lesson/images/speaking-prev-active.png";
const speakingNext = "https://rwstatic.tentons.cn/web/Lesson/images/speaking-next.png";
const speakingNextActive = "https://rwstatic.tentons.cn/web/Lesson/images/speaking-next-active.png";

const { delayShow } = useDelayShow();
const fs = uni.getFileSystemManager();
const height = ref(getApp().globalData!.pageTop);
const processTopHeight = ref(getApp().globalData!.pageProcessTop);

const recordRef = ref(null);
const isUpdate = ref(true);

const subTitle = ref("");
const headerTitle = ref("");
const stepWidth = ref(0);
const session_id = ref("");
const skillId = ref(0);
const speakerRef = ref(null);
const studyNum = ref(0); // 学习次数
const studyTime = ref(1); // 学习时长
let timer: number | undefined;

const skillResults = ref<ISkillResult>({
  score: 0,
  scoreLimit: 0,
  time_long: 0,
  study_num: 0,
  days: 0,
  skillData: [{
    part_id: "",
    symbol: "",
    practiceList: [],
  }],
});

const questionArray = ref<any[]>([{
  type: 1,
}]);
const currentQuestionIndex = ref(0);
const isLearnFinish = ref(false);
const isPrevSwitch = ref(false);
const isRelearn = ref(false);
const isReStart = ref(false);

onLoad(async (option: any) => {
  session_id.value = option.section_id;

  if (option.data) {
    const result: ILessonResult = JSON.parse(decodeURIComponent(option.data));
    handleInitData(result);
  }
})

const handleInitData = (result: ILessonResult) => {
  const tempDate = result.data.result;

  skillId.value = result.data.skillId;
  isRelearn.value = result.data.isRelearn;
  isLearnFinish.value = result.data.isLearnFinish;
  subTitle.value = result.sub_title;

  if (!isLearnFinish.value) {
    timer = setInterval(() => {
      studyTime.value += 1;
    }, 1000);
    questionArray.value = result.data.questionArray;
    currentQuestionIndex.value = result.data.currentQuestionIndex;
    stepWidth.value = 100 / result.data.nodeTotalNum;
    headerTitle.value = result.sub_title;
  } else {
    headerTitle.value = "小结";
    skillResults.value = tempDate;
  }
}

const progress = computed(() => {
  return currentQuestionIndex.value * stepWidth.value;
})

const currentQuestion = computed(() => {
  return questionArray.value[currentQuestionIndex.value];
})

const prevIconUrl = computed(() => {
  return currentQuestionIndex.value > 0 ? speakingPrevActive : speakingPrev;
})

const nextIconUrl = computed(() => {
  return currentQuestionIndex.value < questionArray.value.length - 1 ? speakingNextActive : speakingNext;
})

const updateCurrentQuestion = (res: any) => {
  const temp = questionArray.value[currentQuestionIndex.value];
  questionArray.value[currentQuestionIndex.value] = Object.assign(temp, res);
}

const handleVideoNodeReport = async (val: { process: number, isSumVideo: boolean }) => {
  const { process, isSumVideo } = val;

  questionArray.value[currentQuestionIndex.value].video_process = process;

  if ((isPrevSwitch.value || process == 2) && currentQuestionIndex.value < questionArray.value.length - 1) {
    currentQuestionIndex.value += 1;
    isPrevSwitch.value = false;
  }

  if (isSumVideo) {
    isLearnFinish.value = true;

    await handleNodeReport();

    const result: ILessonResult = await requestSoundExplanationData(skillId.value, 100);
    handleInitData(result);

    isRelearn.value = false;
  }
}

const onRecorderSuccess = (info: IUploadSuccessInfo) => {
  util.showLoading();

  fs.readFile({
    filePath: info.localFilePath,
    success: (file) => {
      startEvaluating({
        evaluatingInfo: { sentence: currentQuestion.value.practice, isPhoneme: currentQuestion.value.type === 0 ? true : false },
        audioBuffer: file.data as ArrayBuffer,
        onSuccess: async (res) => {
          studyNum.value += 1;
          const result = await API.skillReport({
            session_id: session_id.value,
            datas: [{
              user_voice: info.ossFilePath,
              analysis: JSON.stringify(res),
              practice_id: currentQuestion.value.practice_id,
            }]
          })
          const temp = questionArray.value[currentQuestionIndex.value];

          questionArray.value[currentQuestionIndex.value].user_voice = info.ossFilePath;
          // @ts-ignore
          questionArray.value[currentQuestionIndex.value] = Object.assign(temp, result!.analysisList[0]);

          setTimeout(() => {
            util.hideLoading();
          }, 300);
        },
        onError: (errMsg) => {
          console.log(errMsg);
          util.showDialogue(errMsg);
          util.hideLoading();
        },
      })
    },
    fail: (errMsg) => {
      console.log(errMsg);
      util.hideLoading();
      util.showDialogue("找不到音频文件");
    }
  })
}

const handleListenOriginVoice = () => {
  if (currentQuestion.value.us_voice) {
    (speakerRef.value as any).handleClick();
  }
}

const handleToPrev = async () => {
  if (currentQuestionIndex.value <= 0) {
    return;
  }

  isUpdate.value = false;
  currentQuestionIndex.value -= 1;
  await nextTick();
  isUpdate.value = true;
  isPrevSwitch.value = true;
}

const handleToNext = async () => {
  if (currentQuestionIndex.value >= questionArray.value.length - 1) {
    isLearnFinish.value = true;

    await handleNodeReport();
    const result: ILessonResult = await requestSoundExplanationData(skillId.value, 100);
    handleInitData(result);

    isRelearn.value = false;
    return;
  }

  if (!currentQuestion.value.user_voice) {
    return util.showDialogue("完成练习才能切换下一题");
  }

  isUpdate.value = false;
  currentQuestionIndex.value += 1;

  await nextTick();
  isUpdate.value = true;
}

const handleReStart = async (headerTitle: string) => {
  const result: ILessonResult = await requestSoundExplanationData(skillId.value, 0);
  isReStart.value = true;

  const temp = Object.assign(result, { sub_title: headerTitle });
  handleInitData(temp);
}

const handleNodeReport = async () => {
  clearInterval(timer);

  API.skillNodeReport({
    study_num: studyNum.value,
    time_long: studyTime.value,
    session_id: session_id.value,
  }).finally(() => {
    studyTime.value = 0;
  })
}

onBeforeUnmount(async () => {
  if (!isLearnFinish.value) {
    await handleNodeReport();
  }
});
</script>

<style scoped lang="scss">
.page-wrapper {
  position: relative;
  width: 100%;
  height: calc(100% - 0.7rem);
  overflow: hidden;

  .wrapper-sentence {
    position: relative;
    width: 100%;
    height: calc(100% - 9.7rem);
  }

  .wrapper-result {
    height: 100%;
  }

  .operate-buttons {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 4.7rem;
    height: 5rem;

    .button-wrapper {
      display: flex;
      align-items: center;
      justify-content: space-between;
      height: 5rem;
      padding: 0.5rem 3rem 0;

      .wrapper-switch {
        width: 3rem;
        height: 3rem;
      }

      .wrapper-btn {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 5rem;
        margin: 0;
        font-family: xiaolai;
        font-size: 1.7rem;
        border-radius: 1rem;
        color: $uni-text-color;
        border: 2px solid $uni-btn-border;

        .btn-icon {
          width: 2.8rem;
          height: 2.8rem;
          margin-right: 0.7rem;
        }
      }

      .prime {
        background-color: $uni-btn-prime;
      }

      .minor {
        background-color: $uni-btn-minor;
      }

      .is-hover {
        color: rgba(255, 255, 255, 0.6);
      }
    }
  }
}
</style>